package com.toKnow.controller;

import com.toKnow.model.dto.UserEditNormalDTO;
import com.toKnow.model.dto.UserInfoDTO;
import com.toKnow.model.entity.UserInfo;
import com.toKnow.model.vo.*;
import com.toKnow.model.vo.transfer.UserEditNormalVOTransfer;
import com.toKnow.model.vo.transfer.UserInfoVOTransfer;
import com.toKnow.service.ProfileService;
import com.toKnow.utils.FormatUtil;
import com.toKnow.utils.JwtActivateUtil;
import com.toKnow.utils.JwtUserSessionUtil;
import com.toKnow.utils.SessionAndCookieUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;

/**
 * 修改用户信息，包括普通信息，和账户信息（邮箱、密码）
 */
@Controller
@RequestMapping(value = "/api/user")
public class ProfileController {

    @Resource
    private ProfileService profileService;

    // changed

    /**
     * 用户信息，返回除了userpwd、activateCode以外的所有信息
     * /user/info/content
     * GET{}{commonResult}
     */
    @RequestMapping(value = "/info/content")
    @ResponseBody
    public CommonResult showContent(HttpSession session){
        CommonResult cm = new CommonResult();
        cm.setSuccess(false); //默认为false
        String userToken = (String) session.getAttribute("userToken");
        if(JwtUserSessionUtil.verify(userToken)){
            String username = JwtUserSessionUtil.getInfo(userToken, "username");
            UserInfoDTO userInfoDTO = profileService.getUserInfo("username", username);
            if(userInfoDTO != null){
                UserInfoVO userInfoVO = UserInfoVOTransfer.INSTANCE.fromUserInfoDTO(userInfoDTO);
                cm.setSuccess(true);
                cm.setMessage("");
                cm.setObject(userInfoVO);
            }else{
                cm.setMessage("没有该用户");
            }
        }else{
            cm.setMessage("Token错误");
        }
        return cm;
    }

    /**
     * ajax请求：用户修改普通信息，检查用户名是否重复，并更新头像
     * /user/info/edit/normal
     * POST{userEditNormalVO}{commonResult}
     */
    // 修改普通信息
    // transactional right
    @RequestMapping(value = "/info/edit/normal", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult editNormal(HttpServletRequest request, HttpServletResponse response, HttpSession session,
                                   UserEditNormalVO userEditNormalVO, MultipartFile avatar) {
        CommonResult cm = new CommonResult();
        cm.setSuccess(false); //默认false
        String userToken = (String) session.getAttribute("userToken");
        if (JwtUserSessionUtil.verify(userToken)) {
            //根据session中的用户id、前端传的vo、file修改普通信息
            Integer id = Integer.valueOf(Objects.requireNonNull(JwtUserSessionUtil.getInfo(userToken, "id")));
            UserEditNormalDTO userEditNormalDTO = UserEditNormalVOTransfer.INSTANCE.toUserEditNormalDTO(userEditNormalVO);
            String message = profileService.modifyUserNormal(request, id, avatar, userEditNormalDTO);
            boolean success = message.equals("");
            cm.setSuccess(success);
            cm.setMessage(message);
            //如果成功修改了用户名，还需要更新session和cookie中的信息
            String originalUsername = JwtUserSessionUtil.getInfo(userToken, "username");
            String newUsername = userEditNormalVO.getUsername();
            if (success && !Objects.equals(originalUsername, newUsername)) { // 修改了用户名
                String userpwd = JwtUserSessionUtil.getInfo(userToken, "userpwd");
                // 更新session
                SessionAndCookieUtil.setUserSession(request, String.valueOf(id), newUsername, userpwd);
                // 更新cookie
                SessionAndCookieUtil.setUserCookie(request, response, newUsername, userpwd, 60 * 60 * 24 * 10);
            }
        } else {
            cm.setMessage("Token错误");
        }
        return cm;
    }

    /**
     * ajax请求：修改用户邮箱，检查邮箱是否重复密码是否正确，如果检查通过则发送修改邮件
     * /user/info/edit/email
     * POST{email:String, userpwd:String}{commonResult}
     */
    // transactional right
    @RequestMapping(value = "/info/edit/email", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult editEmail(HttpServletRequest request, HttpSession session, String email, String userpwd){
        CommonResult cm = new CommonResult(); //默认失败
        cm.setSuccess(false);
        cm.setMessage("Token错误");
        String userToken = (String) session.getAttribute("userToken");
        if(JwtUserSessionUtil.verify(userToken)){
            Integer id = Integer.valueOf(Objects.requireNonNull(JwtUserSessionUtil.getInfo(userToken, "id")));
            String realUserpwd = JwtUserSessionUtil.getInfo(userToken, "userpwd");
            if(userpwd != null && realUserpwd != null){
                if(realUserpwd.equals(userpwd)) {
                    String hint = profileService.tryToModifyUserAccount(request, id, "email", email);
                    if(hint.equals("")) {
                        cm.setSuccess(true);
                        cm.setMessage(("请查收新邮箱以确认修改"));
                    } else {
                        cm.setMessage(hint);
                    }
                } else {
                    cm.setMessage("密码错误");
                }
            }else{
                cm.setMessage("请输入密码");
            }
        }
        return cm;
    }

    /**
     * 确认修改用户邮箱
     * /info/edit/email/confirm
     * GET{activateCode:String}{}
     */
    // transactional right
    @RequestMapping(value = "/info/edit/email/confirm")
    public ModelAndView editEmailConfirm(String activateToken){
        ModelAndView mv = new ModelAndView();
        CommonResult cm = new CommonResult();
        String message = "Token错误"; // 默认未激活
        if(JwtActivateUtil.verify(activateToken)){ // token有效则进行激活操作
            String username = JwtActivateUtil.getInfo(activateToken, "username");
            String email = JwtActivateUtil.getInfo(activateToken, "email");
            String activateCode = JwtActivateUtil.getInfo(activateToken, "activateCode");
            message = profileService.modifyUserAccount(username, activateCode, "email", email);
        }
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        mv.addObject("commonResult", cm);
        mv.setViewName("redirect:/"); //进入首页
        return mv;
    }

    /**
     * ajax请求：修改用户密码，检查新密码是否符合规范，如果旧密码正确就直接改，否则检查通过则发送修改密码点击则修改且重新登录
     * /user/info/edit/userpwd
     * POST{userpwd:String, oldpwd:String}{commonResult}
     */
    @RequestMapping(value = "/info/edit/userpwd", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult editUserpwd(HttpServletRequest request, HttpServletResponse response, HttpSession session,
                                    String oldpwd, String userpwd){
        CommonResult cm = new CommonResult(); //默认失败
        cm.setSuccess(false);
        cm.setMessage("Token错误");
        String userToken = (String) session.getAttribute("userToken");
        if(JwtUserSessionUtil.verify(userToken)){
            Integer id = Integer.valueOf(Objects.requireNonNull(JwtUserSessionUtil.getInfo(userToken, "id")));
            String username = JwtUserSessionUtil.getInfo(userToken, "username");
            String oldUserpwd = JwtUserSessionUtil.getInfo(userToken, "userpwd");
            // 如果输入了旧密码直接检测旧密码是否正确，正确的话就直接改不必发邮箱
            if(oldpwd != null && oldUserpwd != null){
                if(oldpwd.equals(oldUserpwd)) {
                    String hint = FormatUtil.checkUserpwd(userpwd);
                    if(hint.equals("")){ //验证密码成功

                        String message = profileService.modifyUserPassword(username, userpwd);
                        if(message.equals("")) {
                            cm.setSuccess(true);
                            cm.setMessage("修改成功");
                        } else {
                            cm.setSuccess(false);
                            cm.setMessage("修改失败，请重试");
                        }

//                        //设置session
//                        SessionAndCookieUtil.setUserSession(request, String.valueOf(id), username, userpwd);
//                        //设置cookie
//                        SessionAndCookieUtil.setUserCookie(request, response, username, userpwd, 60 * 60 * 24 * 10);
                    }else{ // 新密码不合规范
                        cm.setMessage("密码至少要包含一个字母，一个数字和一个特殊字符");
                    }
                } else {
                    cm.setMessage("密码错误！");
                }
            }else{
                String hint = profileService.tryToModifyUserAccount(request, id, "userpwd", userpwd);
                if(hint.equals("")){ //发送邮箱成功
                    cm.setSuccess(true);
                    cm.setMessage("请查收邮箱确认修改");
                }else{ //发送邮箱失败
                    cm.setMessage(hint);
                }
            }
        }
        return cm;
    }

    /**
     * 确认修改用户密码
     * /info/edit/password/confirm
     * GET{activateCode:String}{}
     */
    @RequestMapping(value = "/info/edit/userpwd/confirm")
    public ModelAndView editPasswordConfirm(HttpServletRequest request, HttpServletResponse response, HttpSession session,
                                            String activateToken){
        ModelAndView mv = new ModelAndView();
        CommonResult cm = new CommonResult();
        String message = "Token错误"; // 默认未激活
        String username = null;
        String userpwd = null;
        if(JwtActivateUtil.verify(activateToken)){ // token有效则进行激活操作
            username = JwtActivateUtil.getInfo(activateToken, "username");
            userpwd = JwtActivateUtil.getInfo(activateToken, "userpwd");
            String activateCode = JwtActivateUtil.getInfo(activateToken, "activateCode");
            message = profileService.modifyUserAccount(username, activateCode, "userpwd", userpwd);
        }
//        if(message.equals("")){
//            String originalUserSessionToken = (String) session.getAttribute("userToken");
//            String id = JwtUserSessionUtil.getInfo(originalUserSessionToken, "id");
//            //设置session
//            SessionAndCookieUtil.setUserSession(request, String.valueOf(id), username, userpwd);
//            //设置cookie
//            SessionAndCookieUtil.setUserCookie(request, response, username, userpwd, 60 * 60 * 24 * 10);
//        }
        cm.setSuccess(message.equals(""));
        cm.setMessage(message);
        mv.addObject("commonResult", cm);
        mv.setViewName("redirect:/"); //进入首页
        return mv;
    }
}
